/*
 * Put all the libraries from "lib" folder into Classpath
 * 
 * Client Authentication (in getMethodTest())
 * Show all user (GET)
 * Show particular user operation (GET) (3rd user)
 * Update user (PUT) (4th user)
 * Delete user (DELETE) (4th User)
 * 
 * 
 */

import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.*;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import com.sun.org.apache.xerces.internal.parsers.DOMParser;

import java.io.*;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class httpClient {

	public static void parseXMLFile(String xmlResponse) {

		try {

			InputSource inputSource = new InputSource(new StringReader(
					xmlResponse));
			DOMParser domParser = new DOMParser();
			domParser.parse(inputSource);
			Document documentData = domParser.getDocument();
			NodeList usersNodes = documentData.getElementsByTagName("user");
			Node usersNode = null;
			Node node = null;
			for (int i = 0; i < usersNodes.getLength(); i++) {
				usersNode = usersNodes.item(i);
				NodeList userList = usersNode.getChildNodes();
				String approvedType = null;
				String createdAt = null;
				String email = null;
				int id = 0;
				String joined = null;
				String password = null;
				String role = null;
				String updatedAt = null;
				String userName = null;
				if (userList != null) {
					for (int l = 0; l < userList.getLength(); l++) {
						Node userData = userList.item(l);
						if (userData.getNodeName().equalsIgnoreCase("approved")) {
							approvedType = userData.getTextContent();
							System.out.print(approvedType + "\t");
						}
						if (userData.getNodeName().equalsIgnoreCase(
								"created-at")) {
							createdAt = userData.getTextContent();
							System.out.print(createdAt + "\t");

						}
						if (userData.getNodeName().equalsIgnoreCase("email")) {
							email = userData.getTextContent();
							System.out.print(email + "\t");
						}
						if (userData.getNodeName().equalsIgnoreCase("id")) {
							id = Integer.parseInt(userData.getTextContent());
							System.out.print(id + "\t");
						}
						if (userData.getNodeName().equalsIgnoreCase("joined")) {
							joined = userData.getTextContent();
							System.out.print(joined + "\t");
						}
						if (userData.getNodeName().equalsIgnoreCase("password")) {
							password = userData.getTextContent();
							System.out.print(password + "\t");
						}
						if (userData.getNodeName().equalsIgnoreCase(
								"updated-at")) {
							updatedAt = userData.getTextContent();
							System.out.print(updatedAt + "\t");
						}
						if (userData.getNodeName().equalsIgnoreCase("username")) {
							userName = userData.getTextContent();
							System.out.println(userName + "\t");
						}
					}

				}
			}

		} catch (SAXException ex) {
			System.out.println(ex);
		} catch (IOException ex) {
			System.out.println(ex);
		}

	}

	public static void GetMethodTest(String url, HttpClient httpDemoClient) {
		Credentials credentials = new UsernamePasswordCredentials("admin",
				"admin");
		httpDemoClient.getState().setCredentials(
				new AuthScope(url, 443, "realm"), credentials);

		GetMethod getMethodDemo = new GetMethod(url);
		PostMethod postMethod = new PostMethod(url);
		getMethodDemo.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
				new DefaultHttpMethodRetryHandler(3, false));

		getMethodDemo.setDoAuthentication(true);
		
		try {
			int returnValue = httpDemoClient.executeMethod(getMethodDemo);
			if (returnValue != HttpStatus.SC_OK) {
				System.err.println(" Problem in method execution :"
						+ getMethodDemo.getStatusLine());
			}
			byte[] dataInResponse = getMethodDemo.getResponseBody();

			parseXMLFile(new String(dataInResponse));

		} catch (HttpException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			getMethodDemo.releaseConnection();
		}
	}

	public static void putMethodTest(HttpClient httpDemoClient) throws HttpException, IOException
	{
		PutMethod putmethod ;
		String bodyInformation ="<?xml version='1.0' encoding='UTF-8'?> "+
								"<user> "+
								"<approved type=\"boolean\" nil=\"true\"/> "+
								"<email>user1@yahoo.com</email> "+
								"<joined type=\"date\" nil=\"true\"/>" +
								"<password>user4_update</password> "+
								"<role type=\"integer\" nil=\"true\"/>" +
								"<username>user4_update</username>"+
								"</user>";			
		
		putmethod=new PutMethod("http://localhost:3000/users/4");
		//putmethod.getParams().setBooleanParameter(HttpMethodParams.USE_EXPECT_CONTINUE,true);
		//System.out.println(bodyInformation);
		RequestEntity requestEntity = new StringRequestEntity(bodyInformation, "application/xml", "UTF-8");
		//RequestEntity requestEntity = new InputStreamRequestEntity(new FileInputStream("C:\\cmpe275\\HttpClient\\input.txt"));
		putmethod.setRequestEntity(requestEntity);
		httpDemoClient.getHttpConnectionManager().getParams().setConnectionTimeout(5000);

		int retrunid=httpDemoClient.executeMethod(putmethod);
		System.out.println("\n*************************************************");
		System.out.println("\t After Uploading/Updating User4");
		System.out.println("*************************************************");
		if (retrunid == HttpStatus.SC_OK) {
	        System.out.println("Upload complete..");
	    } else {
	      System.err.println("Upload failed..");
	    }
		String putUser4URL = "http://localhost:3000/users/4.xml";
		GetMethodTest(putUser4URL, httpDemoClient);

		putmethod.releaseConnection();
	}
	
	public static void deleteMethodTest(HttpClient httpDemoClient) throws HttpException, IOException
	{
		DeleteMethod deletemethod =new DeleteMethod("http://localhost:3000/users/4.xml");
		int returnid=httpDemoClient.executeMethod(deletemethod);
		System.out.println("\n*************************************************");
		System.out.println("\t After deletion 2nd user");
		System.out.println("*************************************************");
		if (returnid == HttpStatus.SC_OK) {
	        System.out.println("Delete complete..");
	        System.out.println("Intensionally showing an error below to confirm the deletion... :)");
	    } else {
	      System.err.println("Delete failed..");
	    }
		String deleteUser4URL = "http://localhost:3000/users/4.xml";
		GetMethodTest(deleteUser4URL, httpDemoClient);
		deletemethod.releaseConnection();
	}
	
	public static void main(String args[]) throws IOException {
		HttpClient httpDemoClient = new HttpClient();
		System.out.println("*************************************************");
		System.out.println("\t Showing all users");
		System.out.println("*************************************************");
		String allUserURL = "http://localhost:3000/users.xml";
		GetMethodTest(allUserURL, httpDemoClient);

		System.out
				.println("\n*************************************************");
		System.out.println("\t Showing one perticular users");
		System.out.println("*************************************************");
		String oneUserURL = "http://localhost:3000/users/3.xml";
		GetMethodTest(oneUserURL, httpDemoClient);
		
		putMethodTest(httpDemoClient);
		
		deleteMethodTest(httpDemoClient);	
		 

	}

}
